package client.ftp;

import it.sauronsoftware.ftp4j.FTPAbortedException;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferException;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPIllegalReplyException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * Extends the FileTransfer class and provides additional methods that are 
 * specific for file transfers for FTP only. Let's you connect, disconnect,
 * login, upload and download files.
 * @author Robert
 */
public class FTPHandler extends FileTransfer {

    /**
     * this FTPClient is part of the ftp4j library
     */
    protected FTPClient client;

    /**
     * Sole constructor. Besides the provided parameters, it also
     * creates a new instance of a FTPClient.
     * @param hostname the name of the server to connect to (IP address or domain name)
     * @param username the user name of the account
     * @param password the password of the account
     * @param port the port number to connect to
     */
    public FTPHandler(String hostname, String username, String password, int port) {
        super(hostname, username, password, port);
        this.client = new FTPClient();
    }

    /**
     * Opens a new connection to an ftp server.
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     */
    protected int connect() {
        try {
            client.connect(hostname, port);
            printMessage("Connected to " + hostname + " at port " + port + " using FTP");
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        }
        return 0;
    }

    /**
     * Closes a existing connection to an ftp server.
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     */
    protected int disconnect() {
        try {
            if (client.isConnected()) {
                client.disconnect(true);
                printMessage("Disconnected from " + hostname);
            } else {
                printMessage("Already disconnected");
            }
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        }
        return 0;
    }

    /**
     * Lets a user log in to a ftp server
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     */
    protected int login() {
        try {
            client.login(username, password);
            printMessage("Logged in with " + username);
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        }
        return 0;
    }

    /**
     * Downloads a file from an ftp server.
     * @param remoteFile the file path where the file is located on the server
     * @param localFolder the path of the directory where to save it
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException,5=FileNotFoundException,6=FTPDataTransferException,7=FTPAbortedException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     * @throws FileNotFoundException
     * @throws FTPDataTransferException
     * @throws FTPAbortedException
     */
     protected int download(String remoteFile, String localFolder) {
        try {
            printMessage("Initialize download of "+remoteFile+"...");
            String fileName = new File(remoteFile).getName();
            client.download(remoteFile, new java.io.File(localFolder+fileName), new MyTransferListener());
            printMessage("Successfully downloaded " + remoteFile + " to "+localFolder);
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (FileNotFoundException ex) {
            printError(ex);
            return 5;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        } catch (FTPDataTransferException ex) {
            printError(ex);
            return 6;
        } catch (FTPAbortedException ex) {
            printError(ex);
            return 7;
        }
        return 0;
    }

    /**
     * Uploads a file to an ftp server.
     * @param localFile the file path of the file to be uploaded
     * @param remoteFolder the directory path on the server where to put it
     * @return An integer (0=Success,1=IllegalStateException,2=IOException,3=FTPIllegalReplyException,4=FTPException,5=FileNotFoundException,6=FTPDataTransferException,7=FTPAbortedException)
     * @throws IllegalStateException
     * @throws IOException
     * @throws FTPIllegalReplyException
     * @throws FTPException
     * @throws FileNotFoundException
     * @throws FTPDataTransferException
     * @throws FTPAbortedException
     */
    protected int upload(String localFile, String remoteFolder) {
        try {
            printMessage("Initialize upload of "+localFile+"...");
            client.changeDirectory(remoteFolder);
            client.upload(new java.io.File(localFile), new MyTransferListener());
            printMessage("Successfully uploaded " + localFile + " to " + hostname + remoteFolder);
        } catch (IllegalStateException ex) {
            printError(ex);
            return 1;
        } catch (FileNotFoundException ex) {
            printError("File not found: ", ex);
            return 5;
        } catch (IOException ex) {
            printError(ex);
            return 2;
        } catch (FTPIllegalReplyException ex) {
            printError(ex);
            return 3;
        } catch (FTPException ex) {
            printError(ex);
            return 4;
        } catch (FTPDataTransferException ex) {
            printError(ex);
            return 6;
        } catch (FTPAbortedException ex) {
            printError(ex);
            return 7;
        }
        return 0;
    }
}
